Data Read-in
https://docs.google.com/spreadsheets/d/1nDXokcwtq_J8A6Uh7zAxsWW16MtcEC_1EiLstz4WGig/edit#gid=1782979571
Social_2022_rawNA_data <- readr::read_csv("DATA/Social Query 2022 NA Campaigns.csv") %>%
clean_names() %>%
filter(date < '2022-07-01') %>%
filter(impressions_analyzed > 10)
Rows: 24117 Columns: 149
-- Column specification ---------------------------------------------------------------------
Delimiter: ","
chr (4): olive_plan_name, platform, olive_placement_type, last_file_date
dbl (99): olive_plan_id, olive_placement_id, brand_id, opid, _1_sec_in_view_impressions,...
lgl (44): active_view_eligible_impressions, active_view_measurable_impressions, active_v...
date (2): date, ingestion_date
i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
Social_2022_rawNA_lookup <- readr::read_csv("DATA/CampaignLookup.csv") %>%
clean_names()
Rows: 9 Columns: 4
-- Column specification ---------------------------------------------------------------------
Delimiter: ","
chr (3): Name, Spend, Quarter
dbl (1): OPID
i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
Social_2022_MOAT_lookup = googlesheets4::read_sheet(
"https://docs.google.com/spreadsheets/d/1nDXokcwtq_J8A6Uh7zAxsWW16MtcEC_1EiLstz4WGig/edit#gid=1782979571") %>%
clean_names() %>%
filter(social == 'Y')
Auto-refreshing stale OAuth token.
√ Reading from Benchmark_Moat_Tile_2022.
√ Range Benchmark_Moat_Tile_2022.
Summary Stats
Placement types distinct
Social_2022_rawNA_data %>%
group_by(platform,olive_placement_type) %>%
summarize (counts = n())
`summarise()` has grouped output by 'platform'. You can override using the `.groups` argument.
Social_2022_rawNA_data %>%
group_by(platform,brand_id) %>%
summarize (counts = n()) %>%
left_join(Social_2022_MOAT_lookup, by = 'brand_id')
`summarise()` has grouped output by 'platform'. You can override using the `.groups` argument.
Social_2022_processedNA_data <-
Social_2022_rawNA_data %>%
select(
olive_plan_id:opid, impressions_analyzed,
x2_sec_video_in_view_impressions, in_view_impressions, fully_on_screen_3sec_cumulative, player_vis_and_aud_on_complete_sum,
valid_and_avoc, valid_and_viewable, valid_and_viewable_gm, valid_and_fully_on_screen_3sec_cumulative, valid_and_inview_3sec_cumulative
) %>%
rename(platform_old = platform
) %>%
left_join(Social_2022_MOAT_lookup, by = 'brand_id'
) %>%
mutate(
olive_plan_id = as.character(olive_plan_id),
olive_placement_id = as.character(olive_placement_id),
brand_id = as.character(brand_id) ,
opid = as.character(opid)
)
#Look at global moat
Social_2022_processedNA_data %>%
skim()
-- Data Summary ------------------------
Values
Name Piped data
Number of rows 16137
Number of columns 24
_______________________
Column type frequency:
character 13
Date 1
numeric 10
________________________
Group variables None
-- Variable type: character ---------------------------------------------------------------------------------------
# A tibble: 13 x 8
skim_variable n_missing complete_rate min max empty n_unique whitespace
* <chr> <int> <dbl> <int> <int> <int> <int> <int>
1 olive_plan_id 0 1 5 5 0 8 0
2 olive_plan_name 0 1 44 72 0 8 0
3 platform_old 0 1 6 18 0 7 0
4 olive_placement_id 0 1 7 7 0 364 0
5 olive_placement_type 0 1 15 27 0 3 0
6 brand_id 0 1 5 7 0 14 0
7 opid 0 1 7 7 0 364 0
8 dataset_name 0 1 20 51 0 14 0
9 region 0 1 2 6 0 2 0
10 channel 0 1 5 7 0 2 0
11 social 0 1 1 1 0 1 0
12 platform 0 1 6 9 0 6 0
13 media_type 0 1 5 15 0 4 0
-- Variable type: Date --------------------------------------------------------------------------------------------
# A tibble: 1 x 7
skim_variable n_missing complete_rate min max median n_unique
* <chr> <int> <dbl> <date> <date> <date> <int>
1 date 0 1 2022-01-18 2022-06-30 2022-03-03 164
-- Variable type: numeric -----------------------------------------------------------------------------------------
# A tibble: 10 x 11
skim_variable n_missing complete_rate mean sd p0 p25 p50 p75
* <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 impressions_analyzed 0 1 209721. 518214. 11 2222 27191 166005
2 x2_sec_video_in_view_impressions 6641 0.588 56682. 191926. 0 255. 4414 26352.
3 in_view_impressions 10589 0.344 106745. 228837. 1 311. 39378 121618.
4 fully_on_screen_3sec_cumulative 9578 0.406 39246. 135769. 0 41 1339 17771
5 player_vis_and_aud_on_complete_sum 8659 0.463 864. 2336. 0 0 43 452
6 valid_and_avoc 8659 0.463 862. 2322. 0 0 43 452
7 valid_and_viewable 257 0.984 71189. 202864. 0 124 7672. 55972.
8 valid_and_viewable_gm 11095 0.312 190179. 444404. 0 149 41944 117986.
9 valid_and_fully_on_screen_3sec_cumulative 9578 0.406 39245. 135767. 0 41 1339 17771
10 valid_and_inview_3sec_cumulative 6221 0.614 19872. 83958. 0 57 1502 13010
p100 hist
* <dbl> <chr>
1 9704935 ▇▁▁▁▁
2 6361782 ▇▁▁▁▁
3 6120199 ▇▁▁▁▁
4 5942621 ▇▁▁▁▁
5 34734 ▇▁▁▁▁
6 34040 ▇▁▁▁▁
7 6361782 ▇▁▁▁▁
8 7095033 ▇▁▁▁▁
9 5942621 ▇▁▁▁▁
10 5942621 ▇▁▁▁▁
Plot Impression Level Data
p = Social_2022_processedNA_data %>%
ggplot() +
aes(x = date, y = impressions_analyzed, color = olive_plan_name, fill = olive_plan_name) +
xlab("Date") +
ylab("Impressions") +
ggtitle("Impressions by Campaign") + #fix size
geom_bar(stat = 'identity') +
theme_bw() +
theme(
plot.title = element_text(size=22, hjust = 0.5),
axis.title.y = element_blank()
)
p
ggplotly(p)
LS0tDQp0aXRsZTogIjAxX0RhdGFfUmVhZGluX1N1bW1hcnlfMjAyMk5BX1NvY2lhbCINCmF1dGhvcjogIkRhcnNoYW4gUGF0ZWwiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4NCiAgICBmaWdfd2lkdGg6IDcNCiAgICBmaWdfaGVpZ2h0OiA2DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KI25vdGU6IG5vcm1hbGx5IGluY2x1ZGUgPSBGQUxTRSBmb3IgdGhpcw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKSAjYWxsIGNvZGUgY2h1bmtzIGJ5IGRlZmF1bHQgd2lsbCBiZSBzaG93bg0Kb3B0aW9ucyhrbml0ci50YWJsZS5mb3JtYXQgPSAiaHRtbCIpICN0YWJsZSBmb3JtYXQNCm9wdGlvbnMoZGlnaXRzPTUpICNzZXQgZGlnaXRzIGluIG51bWJlcnMNCm9wdGlvbnMoc2NpcGVuID0gMTAwKSAjZGlnaXRzIHNob3cgYmVmb3JlIHVzaW5nIHNjaWVudGlmaWMgbm90YXRpb24NCmtuaXRyOjpvcHRzX2NodW5rJHNldCh0aWR5Lm9wdHM9bGlzdCh3aWR0aC5jdXRvZmY9ODApLCB0aWR5PVRSVUUpDQojaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCmxpYnJhcnkocGFjbWFuKSAjZm9yIHF1aWNrIGxvYWQvaW5zdGFsbCBvZiBwYWNrYWdlcw0KcF9sb2FkKA0KICBkcGx5ciwgcmVhZHIsIHRpZHl2ZXJzZSxmb3JjYXRzLHB1cnJyLGx1YnJpZGF0ZSwgIyByZWFkaW5nIGluIGRhdGENCiAgamFuaXRvciwgc3FsZGYsZ29vZ2xlc2hlZXRzNCwgIyBhZGRpdGlvbmFsIHRvb2xzIGZvciBkZWFsaW5nIHdpdGggZGF0YQ0KICBza2ltciwNCiAgcnFkYXRhdGFibGUsICMNCiAgc3BsaXRzdGFja3NoYXBlLHN0cmluZ3IsICNzdHJpbmcgcmVsYXRlZCBsaWJyYXJpZXMNCiAga2FibGVFeHRyYSwgZ2dwbG90MiwgcGxvdGx5LGVjaGFydHM0cixnZ3B1YnIsc2NhbGVzLFJDb2xvckJyZXdlcixnZ3RoZW1lcywgI2ZvciB2aXN1YWxpemF0aW9uIG9mIGRhdGENCiAgcmV0aWN1bGF0ZSAjZm9yIHVzaW5nIHB5dGhvbg0KKQ0KYGBgDQoNCiMjIERhdGEgUmVhZC1pbg0KDQo8aHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMW5EWG9rY3d0cV9KOEE2VWg3ekF4c1dXMTZNdGNFQ18xRWlMc3R6NFdHaWcvZWRpdCNnaWQ9MTc4Mjk3OTU3MT4NCg0KYGBge3J9DQpTb2NpYWxfMjAyMl9yYXdOQV9kYXRhIDwtIHJlYWRyOjpyZWFkX2NzdigiREFUQS9Tb2NpYWwgUXVlcnkgMjAyMiBOQSBDYW1wYWlnbnMuY3N2IikgJT4lDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoZGF0ZSA8ICcyMDIyLTA3LTAxJykgJT4lIA0KICBmaWx0ZXIoaW1wcmVzc2lvbnNfYW5hbHl6ZWQgPiAxMCkNCg0KDQpTb2NpYWxfMjAyMl9yYXdOQV9sb29rdXAgPC0gcmVhZHI6OnJlYWRfY3N2KCJEQVRBL0NhbXBhaWduTG9va3VwLmNzdiIpICU+JQ0KICBjbGVhbl9uYW1lcygpDQoNClNvY2lhbF8yMDIyX01PQVRfbG9va3VwID0gZ29vZ2xlc2hlZXRzNDo6cmVhZF9zaGVldCgNCiAgImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFuRFhva2N3dHFfSjhBNlVoN3pBeHNXVzE2TXRjRUNfMUVpTHN0ejRXR2lnL2VkaXQjZ2lkPTE3ODI5Nzk1NzEiKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoc29jaWFsID09ICdZJykNCg0KYGBgDQoNCiMjIFN1bW1hcnkgU3RhdHMNCg0KIyMjIFBsYWNlbWVudCB0eXBlcyBkaXN0aW5jdA0KDQpgYGB7cn0NCg0KU29jaWFsXzIwMjJfcmF3TkFfZGF0YSAlPiUNCiAgZ3JvdXBfYnkocGxhdGZvcm0sb2xpdmVfcGxhY2VtZW50X3R5cGUpICU+JSANCiAgc3VtbWFyaXplIChjb3VudHMgPSBuKCkpDQoNClNvY2lhbF8yMDIyX3Jhd05BX2RhdGEgJT4lDQogIGdyb3VwX2J5KHBsYXRmb3JtLGJyYW5kX2lkKSAlPiUgDQogIHN1bW1hcml6ZSAoY291bnRzID0gbigpKSAlPiUNCiAgbGVmdF9qb2luKFNvY2lhbF8yMDIyX01PQVRfbG9va3VwLCBieSA9ICdicmFuZF9pZCcpDQoNCmBgYA0KDQpgYGB7cn0NCg0KU29jaWFsXzIwMjJfcHJvY2Vzc2VkTkFfZGF0YSA8LQ0KICBTb2NpYWxfMjAyMl9yYXdOQV9kYXRhICU+JQ0KICBzZWxlY3QoDQogICAgb2xpdmVfcGxhbl9pZDpvcGlkLCBpbXByZXNzaW9uc19hbmFseXplZCwNCiAgICB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywgaW5fdmlld19pbXByZXNzaW9ucywgZnVsbHlfb25fc2NyZWVuXzNzZWNfY3VtdWxhdGl2ZSwgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSwNCiAgICB2YWxpZF9hbmRfYXZvYywgdmFsaWRfYW5kX3ZpZXdhYmxlLCB2YWxpZF9hbmRfdmlld2FibGVfZ20sIHZhbGlkX2FuZF9mdWxseV9vbl9zY3JlZW5fM3NlY19jdW11bGF0aXZlLCB2YWxpZF9hbmRfaW52aWV3XzNzZWNfY3VtdWxhdGl2ZQ0KICApICU+JQ0KICByZW5hbWUocGxhdGZvcm1fb2xkID0gcGxhdGZvcm0NCiAgICAgICAgICkgJT4lIA0KICBsZWZ0X2pvaW4oU29jaWFsXzIwMjJfTU9BVF9sb29rdXAsIGJ5ID0gJ2JyYW5kX2lkJw0KICApICU+JSANCiAgbXV0YXRlKA0KICAgIG9saXZlX3BsYW5faWQgPSBhcy5jaGFyYWN0ZXIob2xpdmVfcGxhbl9pZCksDQogICAgb2xpdmVfcGxhY2VtZW50X2lkID0gYXMuY2hhcmFjdGVyKG9saXZlX3BsYWNlbWVudF9pZCksDQogICAgYnJhbmRfaWQgPSBhcy5jaGFyYWN0ZXIoYnJhbmRfaWQpICwNCiAgICBvcGlkID0gYXMuY2hhcmFjdGVyKG9waWQpDQogICkNCg0KI0xvb2sgYXQgZ2xvYmFsIG1vYXQNCg0KU29jaWFsXzIwMjJfcHJvY2Vzc2VkTkFfZGF0YSAlPiUgDQogIHNraW0oKQ0KYGBgDQoNCiMjIyBQbG90IEltcHJlc3Npb24gTGV2ZWwgRGF0YQ0KDQpgYGB7ciwgZmlnLmhlaWdodD0gMTAsIGZpZy53aWR0aD0gMTV9DQoNCnAgPSBTb2NpYWxfMjAyMl9wcm9jZXNzZWROQV9kYXRhICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGFlcyh4ID0gZGF0ZSwgeSA9IGltcHJlc3Npb25zX2FuYWx5emVkLCBjb2xvciA9IG9saXZlX3BsYW5fbmFtZSwgZmlsbCA9IG9saXZlX3BsYW5fbmFtZSkgKw0KICB4bGFiKCJEYXRlIikgKw0KICB5bGFiKCJJbXByZXNzaW9ucyIpICsNCiAgZ2d0aXRsZSgiSW1wcmVzc2lvbnMgYnkgQ2FtcGFpZ24iKSArICNmaXggc2l6ZQ0KZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsNCiAgdGhlbWVfYncoKSArDQogIHRoZW1lKA0KICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjIsIGhqdXN0ID0gMC41KSwNCiAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpDQogICkNCg0KcA0KDQpnZ3Bsb3RseShwKQ0KYGBgDQoNCiMjIyBDYWxjdWxhdGUgVi9WIGFuZCBBVk9DIFJhdGVzIGJ5IFBsYXRmb3JtDQoNCmBgYHtyfQ0KU29jaWFsXzIwMjJfU3VtbWFyaXplZE5BX2RhdGUgPC0NClNvY2lhbF8yMDIyX3Byb2Nlc3NlZE5BX2RhdGEgJT4lDQogIG11dGF0ZSgNCiAgICB2YWxpZF92aWV3YWJsZV9pbXBzID0NCiAgICAgIGNhc2Vfd2hlbigNCiAgICAgICAgcGxhdGZvcm0gPT0gJ1R3aXR0ZXInICYgY2hhbm5lbCA9PSAnRGlzcGxheScgfiB2YWxpZF9hbmRfaW52aWV3XzNzZWNfY3VtdWxhdGl2ZSwNCiAgICAgICAgcGxhdGZvcm0gPT0gJ0xpbmtlZEluJyB+IHgyX3NlY192aWRlb19pbl92aWV3X2ltcHJlc3Npb25zLA0KICAgICAgICBUUlVFIH4gdmFsaWRfYW5kX3ZpZXdhYmxlDQogICAgICApLA0KICAgIGF2b2NfaW1wcyA9IGNhc2Vfd2hlbigNCiAgICBUUlVFIH4gIHBsYXllcl92aXNfYW5kX2F1ZF9vbl9jb21wbGV0ZV9zdW0gDQogICAgKSwNCiAgICBxdWFydGVyID0gbHVicmlkYXRlOjpxdWFydGVyKGRhdGUpLA0KICAgIGNoYW5uZWwgPSBjYXNlX3doZW4oDQogICAgICBjaGFubmVsID09ICdESVNQTEFZJyB+ICdTVEFUSUMnLA0KICAgICAgVFJVRSB+IGNoYW5uZWwNCiAgICApDQogICkgJT4lIA0KICBncm91cF9ieShvbGl2ZV9wbGFuX25hbWUsZGF0ZSwgY2hhbm5lbCwgcGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKA0KICAgIHZhbGlkX3ZpZXdhYmxlX2ltcHMgPSBzdW0odmFsaWRfdmlld2FibGVfaW1wcyksDQogICAgYXZvY19pbXBzID0gc3VtKGF2b2NfaW1wcyksDQogICAgaW1wcmVzc2lvbnMgPSBzdW0oaW1wcmVzc2lvbnNfYW5hbHl6ZWQpLA0KICAgIHF1YXJ0ZXIgPSBtYXgocXVhcnRlcikNCiAgKSAlPiUgDQogIGFycmFuZ2UoZGF0ZSxvbGl2ZV9wbGFuX25hbWUpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX1N1bW1hcml6ZWROQV9kYXRlICU+JSANCiAgZmlsdGVyKHBsYXRmb3JtID09ICdUd2l0dGVyJykgJT4lIA0KICBmaWx0ZXIoY2hhbm5lbCA9PSAnRElTUExBWScpDQoNCmBgYA0KDQpgYGB7cn0NCg0KU29jaWFsXzIwMjJfU3VtbWFyaXplZE5BX2RhdGUgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBwbGF0Zm9ybSwgY2hhbm5lbCkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBBVk9DIFJhdGVgID0gc3VtKGF2b2NfaW1wcykvc3VtKGltcHJlc3Npb25zKQ0KICApICU+JSAgICAgDQogIGtibCgpICU+JSANCiBrYWJsZV9tYXRlcmlhbChjKCJzdHJpcGVkIiwgImhvdmVyIiwiY29uZGVuc2VkIiwicmVzcG9uc2l2ZSIpLGZ1bGxfd2lkdGggPSBGLGZpeGVkX3RoZWFkID0gVCkNCmBgYA0KDQpgYGB7cn0NCndyaXRlX3NoZWV0KFNvY2lhbF8yMDIyX1N1bW1hcml6ZWROQV9kYXRlLCBzcyA9ICdodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xT1Q3em9xYmNuYWRRc1I4ZWhIYnZNZktuOG1pZVdZYS1kVmFDT0hGZGhISS9lZGl0I2dpZD0xNDY5OTc4MDU1JywNCiAgICAgICAgICAgc2hlZXQgPSAnQWdncmVnYXRlZCBEYXRhIE5BJykNCmBgYA0KDQojIyMgQWRkaXRpb25hbCBUd2l0dGVyIExldmVsIEluZm9ybWF0aW9uDQoNCmBgYHtyfQ0KDQpTb2NpYWxfMjAyMl9yYXdOQV9EVjMwX2RhdGEgPC0gcmVhZHI6OnJlYWRfY3N2KCJEQVRBL1NvY2lhbCBRdWVyeSAyMDIyIE5BIERWMzYwLmNzdiIpICU+JQ0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKGRhdGUgPCAnMjAyMi0wNy0wMScpICU+JSANCiAgbXV0YXRlKA0KICAgIG9saXZlX3BsYWNlbWVudF9pZCA9IGFzLmNoYXJhY3RlcihvbGl2ZV9wbGFjZW1lbnRfaWQpDQogICkNCiAgDQoNClNvY2lhbF8yMDIyX3Byb2Nlc3NlZFR3aXR0ZXJOQV9kYXRhIDwtDQpTb2NpYWxfMjAyMl9wcm9jZXNzZWROQV9kYXRhICU+JSBzZWxlY3Qob2xpdmVfcGxhbl9uYW1lLG9saXZlX3BsYWNlbWVudF9pZCxkYXRlLGltcHJlc3Npb25zX2FuYWx5emVkKSAlPiUNCiAgbXV0YXRlKA0KICAgIHF1YXJ0ZXIgPSBxdWFydGVyKGRhdGUpDQogICkgJT4lIA0KICBncm91cF9ieShvbGl2ZV9wbGFuX25hbWUsb2xpdmVfcGxhY2VtZW50X2lkLGRhdGUscXVhcnRlcikgJT4lIA0KICBzdW1tYXJpemUoDQogICAgaW1wcmVzc2lvbnNfYW5hbHl6ZWQgPSBzdW0oaW1wcmVzc2lvbnNfYW5hbHl6ZWQpDQogICkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGxlZnRfam9pbihTb2NpYWxfMjAyMl9yYXdOQV9EVjMwX2RhdGEsIGJ5ID0gYygnb2xpdmVfcGxhY2VtZW50X2lkJywnb2xpdmVfcGxhbl9uYW1lJywgJ2RhdGUnKSkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKG9saXZlX3BsYW5fbmFtZSkpICU+JSANCiAgZmlsdGVyKHBsYXRmb3JtID09ICdUd2l0dGVyIC0gT2ZmaWNpYWwnICYgb2xpdmVfcGxhY2VtZW50X3R5cGUgPT0gJ1N0YW5kYXJkIEJhbm5lciAoQkFOKScpICU+JSANCiAgbXV0YXRlKA0KICAgIGltcHJlc3Npb25zID0gaW1wcmVzc2lvbnNfYW5hbHl6ZWQsDQogICAgcGxhdGZvcm0gPSAnVHdpdHRlcicsDQogICAgY2hhbm5lbCA9ICdTVEFUSUMnLA0KICAgIGF2b2NfaW1wcyA9IE5BLA0KICAgIHZhbGlkX3ZpZXdhYmxlX2ltcHMgPSB2YWxpZF9hbmRfdmlld2FibGVfaW1wcmVzc2lvbnMsDQogICAgVGltZSA9IE5BDQogICkgJT4lIA0KICBzZWxlY3Qob2xpdmVfcGxhbl9uYW1lLAlkYXRlLAljaGFubmVsLAlwbGF0Zm9ybSwJdmFsaWRfdmlld2FibGVfaW1wcywJYXZvY19pbXBzLAlpbXByZXNzaW9ucywJVGltZSwJcXVhcnRlcikNCg0KYGBgDQoNCmBgYHtyfQ0KDQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkTkFfZGF0YV91cGRhdGVkVHdpdHRlciA8LQ0KU29jaWFsXzIwMjJfU3VtbWFyaXplZE5BX2RhdGUgJT4lDQogIGZpbHRlcighKHBsYXRmb3JtID09ICdUd2l0dGVyJyAmIGNoYW5uZWwgPT0gJ1NUQVRJQycpKSAlPiUgICANCiAgYmluZF9yb3dzIChTb2NpYWxfMjAyMl9wcm9jZXNzZWRUd2l0dGVyTkFfZGF0YSkNCg0KYGBgDQoNCiMjIyBVcGRhdGUgVHdpdHRlciBJbmZvcm1hdGlvbg0KDQpgYGB7cn0NCg0KDQp3cml0ZV9zaGVldChTb2NpYWxfMjAyMl9TdW1tYXJpemVkTkFfZGF0YV91cGRhdGVkVHdpdHRlciwgc3MgPSAnaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMU9UN3pvcWJjbmFkUXNSOGVoSGJ2TWZLbjhtaWVXWWEtZFZhQ09IRmRoSEkvZWRpdCNnaWQ9MTQ2OTk3ODA1NScsDQogICAgICAgICAgIHNoZWV0ID0gJ0FkZGl0aW9uYWwgTkEgVHdpdHRlciBEYXRhJykNCg0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIEgxIDIwMjIgTWV0YSBBc2sgKFRvcCA3IENhbXBhaWducykNCg0KIyMgRGF0YSBSZWFkLWluDQoNCltHb29nbGUgU2hlZXQgd2l0aCBCUSBSZXN1bHRzXShodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xUlUwUUdwbm43Rkh0WmFaZkNBMjJrQ2NHcEVlWTF2TGgwcEhrSjlERVpmVS9lZGl0I2dpZD0xNzUyOTg0NTU4KQ0KDQpgYGB7cn0NClNvY2lhbF8yMDIyX3Jhd19Ub3A3TWV0YV9kYXRhID0gZ29vZ2xlc2hlZXRzNDo6cmVhZF9zaGVldCgNCiAgImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFSVTBRR3BubjdGSHRaYVpmQ0EyMmtDY0dwRWVZMXZMaDBwSGtKOURFWmZVL2VkaXQjZ2lkPTE3NTI5ODQ1NTgiKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoaW1wcmVzc2lvbnNfYW5hbHl6ZWQgPiAxMCkNCg0KDQpTb2NpYWxfMjAyMl9NT0FUX2xvb2t1cCA9IGdvb2dsZXNoZWV0czQ6OnJlYWRfc2hlZXQoDQogICJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xbkRYb2tjd3RxX0o4QTZVaDd6QXhzV1cxNk10Y0VDXzFFaUxzdHo0V0dpZy9lZGl0I2dpZD0xNzgyOTc5NTcxIikgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKHNvY2lhbCA9PSAnWScpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX3Jhd19Ub3A3TWV0YV9kYXRhICU+JSANCiAgZ3JvdXBfYnkocGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKGRpc3QgPSBuKCkpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9Ub3A3TWV0YV9kYXRhIDwtDQogIFNvY2lhbF8yMDIyX3Jhd19Ub3A3TWV0YV9kYXRhICU+JQ0KICBmaWx0ZXIocGxhdGZvcm0gPT0gJ0ZhY2Vib29rJykgJT4lIA0KICBzZWxlY3QoDQogICAgb2xpdmVfcGxhbl9pZDpvcGlkLCBpbXByZXNzaW9uc19hbmFseXplZCwNCiAgICB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywgaW5fdmlld19pbXByZXNzaW9ucywgZnVsbHlfb25fc2NyZWVuXzNzZWNfY3VtdWxhdGl2ZSwgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSwNCiAgICB2YWxpZF9hbmRfYXZvYywgdmFsaWRfYW5kX3ZpZXdhYmxlLCB2YWxpZF9hbmRfdmlld2FibGVfZ20sIHZhbGlkX2FuZF9mdWxseV9vbl9zY3JlZW5fM3NlY19jdW11bGF0aXZlLCB2YWxpZF9hbmRfaW52aWV3XzNzZWNfY3VtdWxhdGl2ZQ0KICApICU+JQ0KICByZW5hbWUocGxhdGZvcm1fb2xkID0gcGxhdGZvcm0NCiAgICAgICAgICkgJT4lIA0KICBsZWZ0X2pvaW4oU29jaWFsXzIwMjJfTU9BVF9sb29rdXAsIGJ5ID0gJ2JyYW5kX2lkJw0KICApICU+JSANCiAgbXV0YXRlKA0KICAgIG9saXZlX3BsYW5faWQgPSBhcy5jaGFyYWN0ZXIob2xpdmVfcGxhbl9pZCksDQogICAgb2xpdmVfcGxhY2VtZW50X2lkID0gYXMuY2hhcmFjdGVyKG9saXZlX3BsYWNlbWVudF9pZCksDQogICAgYnJhbmRfaWQgPSBhcy5jaGFyYWN0ZXIoYnJhbmRfaWQpICwNCiAgICBvcGlkID0gYXMuY2hhcmFjdGVyKG9waWQpDQogICkNCg0KI0NoZWNrIE1pc3NpbmcgRGF0YQ0KDQpTb2NpYWxfMjAyMl9wcm9jZXNzZWRfVG9wN01ldGFfZGF0YSAlPiUgDQogIHNraW0oKQ0KDQpgYGANCg0KIyMjIFBsb3QgSW1wcmVzc2lvbiBMZXZlbCBEYXRhDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PSAxMCwgZmlnLndpZHRoPSAyMH0NCg0KcCA9IFNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9Ub3A3TWV0YV9kYXRhICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGFlcyh4ID0gZGF0ZSwgeSA9IGltcHJlc3Npb25zX2FuYWx5emVkLCBjb2xvciA9IG9saXZlX3BsYW5fbmFtZSwgZmlsbCA9IG9saXZlX3BsYW5fbmFtZSkgKw0KICB4bGFiKCJEYXRlIikgKw0KICB5bGFiKCJJbXByZXNzaW9ucyIpICsNCiAgZ2d0aXRsZSgiTWV0YSBJbXByZXNzaW9ucyBieSBDYW1wYWlnbiIpICsgI2ZpeCBzaXplDQpnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKw0KICB0aGVtZV9idygpICsNCiAgdGhlbWUoDQogICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMiwgaGp1c3QgPSAwLjUpLA0KICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KDQpwDQoNCmdncGxvdGx5KHApDQpgYGANCg0KIyMjIENhbGN1bGF0ZSBWL1YgYW5kIEFWT0MgUmF0ZXMgYnkgUGxhdGZvcm0NCg0KYGBge3J9DQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkX1RvcDdNZXRhX2RhdGEgPC0NClNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9Ub3A3TWV0YV9kYXRhICU+JQ0KICBtdXRhdGUoDQogICAgdmFsaWRfdmlld2FibGVfaW1wcyA9DQogICAgICBjYXNlX3doZW4oDQogICAgICAgIHBsYXRmb3JtID09ICdUd2l0dGVyJyAmIGNoYW5uZWwgPT0gJ0Rpc3BsYXknIH4gdmFsaWRfYW5kX2ludmlld18zc2VjX2N1bXVsYXRpdmUsDQogICAgICAgIHBsYXRmb3JtID09ICdMaW5rZWRJbicgfiB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywNCiAgICAgICAgVFJVRSB+IHZhbGlkX2FuZF92aWV3YWJsZQ0KICAgICAgKSwNCiAgICBhdm9jX2ltcHMgPSBjYXNlX3doZW4oDQogICAgaXMubmEocGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSkgfiAwLA0KICAgIFRSVUUgfiAgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSANCiAgICApLA0KICAgIHF1YXJ0ZXIgPSBsdWJyaWRhdGU6OnF1YXJ0ZXIoZGF0ZSksDQogICAgY2hhbm5lbCA9IGNhc2Vfd2hlbigNCiAgICAgIGNoYW5uZWwgPT0gJ0RJU1BMQVknIH4gJ1NUQVRJQycsDQogICAgICBUUlVFIH4gY2hhbm5lbA0KICAgICkNCiAgKSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSxkYXRlLCBjaGFubmVsLCBwbGF0Zm9ybSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgdmFsaWRfdmlld2FibGVfaW1wcyA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKSwNCiAgICBhdm9jX2ltcHMgPSBzdW0oYXZvY19pbXBzKSwNCiAgICBpbXByZXNzaW9ucyA9IHN1bShpbXByZXNzaW9uc19hbmFseXplZCksDQogICAgcXVhcnRlciA9IG1heChxdWFydGVyKQ0KICApICU+JSANCiAgYXJyYW5nZShkYXRlLG9saXZlX3BsYW5fbmFtZSkNCmBgYA0KDQojIyMgU3VtbWFyaXplZCBUYWJsZSAtIENhbXBhaWduDQoNCltTdW1pZiBEb2N1bWVudGF0aW9uXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yMzUyODg2Mi9zdW1tYXJpemUtYWxsLWdyb3VwLXZhbHVlcy1hbmQtYS1jb25kaXRpb25hbC1zdWJzZXQtaW4tdGhlLXNhbWUtY2FsbCkNCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX1N1bW1hcml6ZWRfVG9wN01ldGFfZGF0YSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBWaWRlbyB2cyBTdGF0aWNgID0gMSAtIHN1bShpbXByZXNzaW9uc1tjaGFubmVsID09J1NUQVRJQyddKS9zdW0oaW1wcmVzc2lvbnMpDQogICkgJT4lICAgICANCiAga2JsKCkgJT4lIA0KIGthYmxlX21hdGVyaWFsKGMoInN0cmlwZWQiLCAiaG92ZXIiLCJjb25kZW5zZWQiLCJyZXNwb25zaXZlIiksZnVsbF93aWR0aCA9IEYsZml4ZWRfdGhlYWQgPSBUKQ0KYGBgDQoNCiMjIyBXcml0ZSB0byBHb29nbGUgU2hlZXRzDQoNCmBgYHtyfQ0KDQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkX1RvcDdNZXRhX2RhdGFfVGFibGUgPC0NClNvY2lhbF8yMDIyX1N1bW1hcml6ZWRfVG9wN01ldGFfZGF0YSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBWaWRlbyB2cyBTdGF0aWNgID0gMSAtIHN1bShpbXByZXNzaW9uc1tjaGFubmVsID09J1NUQVRJQyddKS9zdW0oaW1wcmVzc2lvbnMpDQogICkNCg0KYGBgDQoNCmBgYHtyfQ0Kd3JpdGVfc2hlZXQoU29jaWFsXzIwMjJfU3VtbWFyaXplZF9Ub3A3TWV0YV9kYXRhX1RhYmxlLCBzcyA9ICdodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xUlUwUUdwbm43Rkh0WmFaZkNBMjJrQ2NHcEVlWTF2TGgwcEhrSjlERVpmVS9lZGl0I2dpZD0xNzUyOTg0NTU4JywNCiAgICAgICAgICAgc2hlZXQgPSAnQWdncmVnYXRlZCBEYXRhIEZyb20gUicpDQpgYGANCg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIEgxIDIwMjIgTWV0YSBBc2sgKEFkZGl0aW9uYWwgMiBDYW1wYWlnbnMpDQoNCiMjIERhdGEgUmVhZC1pbg0KDQpbR29vZ2xlIFNoZWV0IHdpdGggQlEgUmVzdWx0c10oaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMTlNdkJLWGNCdHY5V2huNHV4YXJLR3Z1TERvRWdzZnJMcklUUGJ0Mmpmcm8vZWRpdCNnaWQ9MzcyNTk0MzEwKQ0KDQpgYGB7cn0NClNvY2lhbF8yMDIyX3Jhd19BZGQyTWV0YV9kYXRhID0gZ29vZ2xlc2hlZXRzNDo6cmVhZF9zaGVldCgNCiAgImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFZZGtFU29ZbHY2ZnpwUVk4NGo0QUI3THc1cWZXOFhLUG1oMkIwZ0FwWUpBL2VkaXQjZ2lkPTE5ODAyMDgxNDAiKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoaW1wcmVzc2lvbnNfYW5hbHl6ZWQgPiAxMCkNCg0KDQpTb2NpYWxfMjAyMl9NT0FUX2xvb2t1cCA9IGdvb2dsZXNoZWV0czQ6OnJlYWRfc2hlZXQoDQogICJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xbkRYb2tjd3RxX0o4QTZVaDd6QXhzV1cxNk10Y0VDXzFFaUxzdHo0V0dpZy9lZGl0I2dpZD0xNzgyOTc5NTcxIikgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKHNvY2lhbCA9PSAnWScpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX3Jhd19BZGQyTWV0YV9kYXRhICU+JSANCiAgZ3JvdXBfYnkocGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKGRpc3QgPSBuKCkpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9BZGQyTWV0YV9kYXRhIDwtDQogIFNvY2lhbF8yMDIyX3Jhd19BZGQyTWV0YV9kYXRhICU+JQ0KICBmaWx0ZXIocGxhdGZvcm0gPT0gJ0ZhY2Vib29rJ3xwbGF0Zm9ybSA9PSAnRmFjZWJvb2svSW5zdGFncmFtJykgJT4lIA0KICBzZWxlY3QoDQogICAgb2xpdmVfcGxhbl9pZDpvcGlkLCBpbXByZXNzaW9uc19hbmFseXplZCwNCiAgICB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywgaW5fdmlld19pbXByZXNzaW9ucywgZnVsbHlfb25fc2NyZWVuXzNzZWNfY3VtdWxhdGl2ZSwgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSwNCiAgICB2YWxpZF9hbmRfYXZvYywgdmFsaWRfYW5kX3ZpZXdhYmxlLCB2YWxpZF9hbmRfdmlld2FibGVfZ20sIHZhbGlkX2FuZF9mdWxseV9vbl9zY3JlZW5fM3NlY19jdW11bGF0aXZlLCB2YWxpZF9hbmRfaW52aWV3XzNzZWNfY3VtdWxhdGl2ZQ0KICApICU+JQ0KICByZW5hbWUocGxhdGZvcm1fb2xkID0gcGxhdGZvcm0NCiAgICAgICAgICkgJT4lIA0KICBsZWZ0X2pvaW4oU29jaWFsXzIwMjJfTU9BVF9sb29rdXAsIGJ5ID0gJ2JyYW5kX2lkJw0KICApICU+JSANCiAgbXV0YXRlKA0KICAgIG9saXZlX3BsYW5faWQgPSBhcy5jaGFyYWN0ZXIob2xpdmVfcGxhbl9pZCksDQogICAgb2xpdmVfcGxhY2VtZW50X2lkID0gYXMuY2hhcmFjdGVyKG9saXZlX3BsYWNlbWVudF9pZCksDQogICAgYnJhbmRfaWQgPSBhcy5jaGFyYWN0ZXIoYnJhbmRfaWQpICwNCiAgICBvcGlkID0gYXMuY2hhcmFjdGVyKG9waWQpDQogICkNCg0KI0NoZWNrIE1pc3NpbmcgRGF0YQ0KDQpTb2NpYWxfMjAyMl9wcm9jZXNzZWRfQWRkMk1ldGFfZGF0YSAlPiUgDQogIHNraW0oKQ0KDQpgYGANCg0KIyMjIFBsb3QgSW1wcmVzc2lvbiBMZXZlbCBEYXRhDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PSAxMCwgZmlnLndpZHRoPSAyMH0NCg0KcCA9IFNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9BZGQyTWV0YV9kYXRhICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGFlcyh4ID0gZGF0ZSwgeSA9IGltcHJlc3Npb25zX2FuYWx5emVkLCBjb2xvciA9IG9saXZlX3BsYW5fbmFtZSwgZmlsbCA9IG9saXZlX3BsYW5fbmFtZSkgKw0KICB4bGFiKCJEYXRlIikgKw0KICB5bGFiKCJJbXByZXNzaW9ucyIpICsNCiAgZ2d0aXRsZSgiTWV0YSBJbXByZXNzaW9ucyBieSBDYW1wYWlnbiIpICsgI2ZpeCBzaXplDQpnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKw0KICB0aGVtZV9idygpICsNCiAgdGhlbWUoDQogICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMiwgaGp1c3QgPSAwLjUpLA0KICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KDQpwDQoNCmdncGxvdGx5KHApDQpgYGANCg0KIyMjIENhbGN1bGF0ZSBWL1YgYW5kIEFWT0MgUmF0ZXMgYnkgUGxhdGZvcm0NCg0KYGBge3J9DQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkX0FkZDJNZXRhX2RhdGEgPC0NClNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9BZGQyTWV0YV9kYXRhICU+JQ0KICBtdXRhdGUoDQogICAgdmFsaWRfdmlld2FibGVfaW1wcyA9DQogICAgICBjYXNlX3doZW4oDQogICAgICAgIHBsYXRmb3JtID09ICdUd2l0dGVyJyAmIGNoYW5uZWwgPT0gJ0Rpc3BsYXknIH4gdmFsaWRfYW5kX2ludmlld18zc2VjX2N1bXVsYXRpdmUsDQogICAgICAgIHBsYXRmb3JtID09ICdMaW5rZWRJbicgfiB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywNCiAgICAgICAgVFJVRSB+IHZhbGlkX2FuZF92aWV3YWJsZQ0KICAgICAgKSwNCiAgICBhdm9jX2ltcHMgPSBjYXNlX3doZW4oDQogICAgaXMubmEocGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSkgfiAwLA0KICAgIFRSVUUgfiAgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSANCiAgICApLA0KICAgIHF1YXJ0ZXIgPSBsdWJyaWRhdGU6OnF1YXJ0ZXIoZGF0ZSksDQogICAgY2hhbm5lbCA9IGNhc2Vfd2hlbigNCiAgICAgIGNoYW5uZWwgPT0gJ0RJU1BMQVknIH4gJ1NUQVRJQycsDQogICAgICBUUlVFIH4gY2hhbm5lbA0KICAgICkNCiAgKSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSxkYXRlLCBjaGFubmVsLCBwbGF0Zm9ybSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgdmFsaWRfdmlld2FibGVfaW1wcyA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKSwNCiAgICBhdm9jX2ltcHMgPSBzdW0oYXZvY19pbXBzKSwNCiAgICBpbXByZXNzaW9ucyA9IHN1bShpbXByZXNzaW9uc19hbmFseXplZCksDQogICAgcXVhcnRlciA9IG1heChxdWFydGVyKQ0KICApICU+JSANCiAgYXJyYW5nZShkYXRlLG9saXZlX3BsYW5fbmFtZSkNCmBgYA0KDQojIyMgU3VtbWFyaXplZCBUYWJsZSAtIENhbXBhaWduDQoNCltTdW1pZiBEb2N1bWVudGF0aW9uXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yMzUyODg2Mi9zdW1tYXJpemUtYWxsLWdyb3VwLXZhbHVlcy1hbmQtYS1jb25kaXRpb25hbC1zdWJzZXQtaW4tdGhlLXNhbWUtY2FsbCkNCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX1N1bW1hcml6ZWRfQWRkMk1ldGFfZGF0YSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBWaWRlbyB2cyBTdGF0aWNgID0gMSAtIHN1bShpbXByZXNzaW9uc1tjaGFubmVsID09J1NUQVRJQyddKS9zdW0oaW1wcmVzc2lvbnMpDQogICkgJT4lICAgICANCiAga2JsKCkgJT4lIA0KIGthYmxlX21hdGVyaWFsKGMoInN0cmlwZWQiLCAiaG92ZXIiLCJjb25kZW5zZWQiLCJyZXNwb25zaXZlIiksZnVsbF93aWR0aCA9IEYsZml4ZWRfdGhlYWQgPSBUKQ0KYGBgDQoNCiMjIyBXcml0ZSB0byBHb29nbGUgU2hlZXRzDQoNCmBgYHtyfQ0KDQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkX0FkZDJNZXRhX2RhdGFfVGFibGUgPC0NClNvY2lhbF8yMDIyX1N1bW1hcml6ZWRfQWRkMk1ldGFfZGF0YSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBWaWRlbyB2cyBTdGF0aWNgID0gMSAtIHN1bShpbXByZXNzaW9uc1tjaGFubmVsID09J1NUQVRJQyddKS9zdW0oaW1wcmVzc2lvbnMpDQogICkNCg0KYGBgDQoNCmBgYHtyfQ0Kd3JpdGVfc2hlZXQoU29jaWFsXzIwMjJfU3VtbWFyaXplZF9BZGQyTWV0YV9kYXRhX1RhYmxlLCBzcyA9ICdodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xUlUwUUdwbm43Rkh0WmFaZkNBMjJrQ2NHcEVlWTF2TGgwcEhrSjlERVpmVS9lZGl0I2dpZD0xNzUyOTg0NTU4JywNCiAgICAgICAgICAgc2hlZXQgPSAnQWRkaXRpb25hbCAyIENhbXBhaWduIERhdGEgRnJvbSBSJykNCmBgYA0KDQoNCg==